/*
点分治主要利用树的重心的一条性质：所有子树大小不超过n/2, 利用该性质，dfs的递归深度为 O(logn)，利用重心点分治操作分为 递归+归并
本题利用点分治求解，先找到重心x，分为三种情况：
    路径在子树中，递归处理
    路径端点包含重心，求出所有这样的路径，找出满足要求的点
    路径横跨子树，先找出所有的端点包含重心的路径，然后再组合，但由于组合的可能是同一棵子树的路径，需要容斥减去这部分
时间复杂度：O(nlog2n)
*/
#define quickread
#ifdef quickread
#include <cstdio> 
template <typename T>
inline void read(T& x)
{
    int c=getchar(), f=1; x=0;
    while(c<'0'||'9'<c) {if(c=='-') f=-1; c=getchar();}
    while('0'<=c&&c<='9') 
        x=(x<<3)+(x<<1)+c-'0', c=getchar();
    x*=f;
}
template <typename T>
inline void quickwrite(T x)
{
    if(x>=10) quickwrite(x/10);
    putchar(x%10+'0');
}
#else 
#include <iostream>
#endif
#include<cstring>
#include<algorithm>
using namespace std;
#define DEBUG

const int N=10010, M=N<<1;
int n, m;
int h[N], e[M], w[M], ne[M], idx;
bool st[N]; //标记节点是否被处理->在分治过程中删除
int p[N], q[N]; //p[]当前子树所有节点到中心的距离 当前子树内的距离

void AddEdge(int a, int b, int c)
{
    e[idx]=b, w[idx]=c, ne[idx]=h[a], h[a]=idx++;
}

int GetSize(int u, int fa) //求子树大小
{
    if(st[u]) return 0;
    int res=1; //u的大小
    for(int i=h[u]; ~i; i=ne[i])
        if(e[i]!=fa)
            res+=GetSize(e[i], u);
    return res;
}

int GetWC(int u, int fa, int tot, int& wc) //求u为根节点的子树的重心wc
{
    if(st[u]) return 0;
    int sum=1, ms=0;//累加子树大小 最大子树大小
    for(int i=h[u]; ~i; i=ne[i])
    {
        int v=e[i];
        if(v==fa) continue;
        int t=GetWC(v, u, tot, wc); //子树重心，t为子树大小
        ms=max(ms, t); //更新最大子树
        sum+=t; //总节点个数
    }
    ms=max(ms, tot-sum); //u此时为根节点，任意一方向均为其子树，降低时间复杂度
    if(ms<=(tot>>1)) wc=u; //u为根节点的子树大小超过总结点的一半，则为重心
    return sum;
}

void GetDist(int u, int fa, int dist, int& qt)
{
    if(st[u]) return;
    q[qt++]=dist; //将当前距离存入q[]中
    for(int i=h[u]; ~i; i=ne[i])
        if(e[i]!=fa)
            GetDist(e[i], u, dist+w[i], qt);
}

int Get(int a[], int k) // 统计满足条件的路径数量函数 a[]路径长度数组
{
    sort(a, a+k);
    int res=0;
    for(int i=k-1, j=-1; i>=0; i--) //双指针法 j当前区间的前一个下标，i区间末尾
    {
        while(j+1<i&&a[j+1]+a[i]<=m) j++;
        j=min(j, i-1);
        res+=j+1;
    }
    return res;
}

int calc(int u) //分治计算函数 处理u所在的树
{
    if(st[u]) return 0; //u已被删除
    int res=0;
    GetWC(u, -1, GetSize(u, -1), u); //得到u为根节点的子树的重心，并变为根节点
    st[u]=true; //u当作重心已被处理

    // 归并
    int pt=0; //p[]大小
    for(int i=h[u]; ~i; i=ne[i])
    {
        int v=e[i], qt=0; //q[]大小
        GetDist(v, -1, w[i], qt); //u->v大小为w[i]
        res-=Get(q, qt); //去重同一节点内符合条件的路径，在p[]中统一处理
        for(int k=0; k<qt; k++) //存到总距离中
        {
            if(q[k]<=m) res++;
            p[pt++]=q[k];
        }
    }
    res+=Get(p, pt); //总方案数
    for(int i=h[u]; ~i; i=ne[i]) res+=calc(e[i]);
    return res;
}

void init()
{
    memset(st, 0, sizeof st);
    memset(h, -1, sizeof h);
    idx=0;
    for(int i=0; i<n-1; i++)
    {
        int a, b, c; read(a), read(b), read(c);
        // printf("%d<->%d  %d\n", a, b, c);
        AddEdge(a, b, c); AddEdge(b, a, c);
    }
}

void solve()
{
    while(scanf("%d %d", &n, &m), n||m)
    {
        // printf("%d %d\n", n, m);
        init();
        quickwrite(calc(0)), puts("");
    }
}

// #undef DEBUG
signed main()
{
    #ifdef DEBUG
        freopen("./in.txt", "r", stdin);
        freopen("./out.txt", "w", stdout);
    #endif
    #ifndef quickread
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    #endif

    int T=1; //scanf("%d", &T);
    while(T--) 
    {
        solve();
    }
    return 0;
}
